using System;
using System.Collections;
using System.Text;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI;
using System.Drawing;
using Microsoft.SharePoint;
using net.windward.api.csharp;
using System.IO;
using System.Net;
using System.Data.Common;
using DevExpress.Web.ASPxEditors;
using DevExpress.Web.ASPxMenu;
using DevExpress.Web.ASPxGridView;
using DevExpress.Web.ASPxTabControl;
using Microsoft.SharePoint.WebControls;
using System.Data;
using net.windward.tags;
using net.windward.utils.ado;
using System.Xml;
using System.Web;
using System.Configuration;
using System.Web.Configuration;
using System.Reflection;
using System.Collections.Generic;
using System.Web.Caching;
using net.windward.util;
using DevExpress.Data;
using log4net;
using Kailua.net.windward.utils;
using WindwardArrow.net.windward.arrow.datasource;

namespace ArrowWebParts
{
    public class ReportGeneratorWebPart : WebPart
    {
        #region fields

        private bool isLicensed = false;

        private Wizard wizzy;

        private Label[] variableNameLabelArray;
        private Label[] variableRequiredLabelArray;
        private Label[] variableTypeLabelArray;
        private TextBox[] variableValueTextBoxArray;
        private DropDownList[] variableValueDropDownListArray;

        private ASPxGridView variableFinalList;
        private SPFileSelector outputFolderSelector;
        private ASPxLabel selDocLibLabel;
        private ASPxLabel three;
        private SPFileSelector rptDefFileSelector;
        private ASPxLabel errorMessage_step1;
        private ASPxLabel errorMessage_step2;
        private ASPxLabel errorMessage_step3;

        private ASPxLabel template_val;
        private ASPxLabel reportFormat_val;
        private ASPxLabel outputDestination_val;
        private ASPxLabel reportName_val;
        private ASPxLabel finalStatus;
        private LiteralControl finalLiteral;
        private ASPxTextBox reportName;

        ASPxButton docxButton;

        ASPxButton xlsxButton;
        ASPxButton pptxButton;
        ASPxButton pdfButton;
        ASPxButton htmlButton;
        ASPxButton xmlButton;
        ASPxButton rtfButton;
        ASPxButton smlButton;
        ASPxButton xlsButton;

        static string imageDir = "_layouts/1033/images/arrow/";

        string overviewImage = imageDir + "overviewStepRunReport.png";
        string variableImage = imageDir + "dataStep.png";
        string outputImage = imageDir + "outputStep_final.png";
        string reviewImage = imageDir + "reviewStep_final.png";
        string templateImage = imageDir + "templateStep.png";

        private System.Collections.Generic.Dictionary<string, string> formatImages;
        private const string RPT_DOCX = "DOCX";
        private const string RPT_SML = "SML";
        private const string RPT_PDF = "PDF";
        private const string RPT_PPTX = "PPTX";
        private const string RPT_RTF = "RTF";
        private const string RPT_WML = "WML";
        private const string RPT_XLS = "XLS";
        private const string RPT_XLSX = "XLSX";
        private const string RPT_HTML = "HTML";
        
        /// <summary>
        /// folderOutGUID key name. ViewState property contains a GUID string.
        /// </summary>
        private static readonly string VS_OUT_FOLDR_GUID = "folderOutGUID";
        /// <summary>
        /// OutputDocLibGUID key name. ViewState property contains a GUID string.
        /// </summary>
        private static readonly string VS_OUT_DOC_LIB_GUID = "OutputDocLibGUID";
        /// <summary>
        /// OutputSiteGUID key name. ViewState property contains a GUID string.
        /// </summary>
        private static readonly string VS_OUT_SITE_GUID = "OutputSiteGUID";
        /// <summary>
        /// OutputDestination key name. ViewState property contains a GUID string.
        /// </summary>
        private static readonly string VS_OUT_DEST = "OutputDestination";
        /// <summary>
        /// OutputFormat key name. ViewState property contains a windward output format string.
        /// </summary>
        private static readonly string VS_OUT_FORMT = "OutputFormat";
        /// <summary>
        /// ReportName key name. ViewState contains a string.
        /// </summary>
        private static readonly string VS_RPT_NAME = "ReportName";
        /// <summary>
        /// TemplateGUID key name. ViewState property contains a GUID string.
        /// </summary>
        private static readonly string VS_TEMPL_GUID = "TemplateGUID";
        /// <summary>
        /// TemplateName key name. ViewState property contains a string.
        /// </summary>
        private static readonly string VS_TEMPL_NAME = "TemplateName";
        /// <summary>
        /// TemplateExtension key name. ViewState property contains a string.
        /// </summary>
        private static readonly string VS_TEMPL_EXT = "TemplateExtension";
        /// <summary>
        /// TemplateDocLibGUID key name. ViewState property contains a GUID string.
        /// </summary>
        private static readonly string VS_TEMPL_LIB_GUID = "TemplateDocLibGUID";
        /// <summary>
        /// TemplateSiteGUID key name. ViewState property contains a GUID string.
        /// </summary>
        private static readonly string VS_TEMPL_SITE_GUID = "TemplateSiteGUID";
        /// <summary>
        /// kpdKeys key name. ViewState variable contains string[].
        /// </summary>
        private static readonly string VS_KPD_KEYS = "kpdKeys";
        /// <summary>
        /// kpdValues key name. ViewState variable contains string[].
        /// </summary>
        private static readonly string VS_KPD_VALS = "kpdValues";

        private static ILog log = LogManager.GetLogger(typeof(ReportGeneratorWebPart));

        //Embed some javascript for Handling Events Client side, filtering only the ones that need a postback
        private const string filterIncludeScriptKey = "myFilterIncludeScript";
        private const string EmbeddedScriptFormat_itemClick =
            "<script type='text/javascript'>\n" +
            "  function itemClickFilter(s, e){ \n" +
            "    e.processOnServer = \n" +
            "      (e.item.GetImageUrl().indexOf('itdl.gif') != -1) || \n" +
            "      (e.item.GetImageUrl().indexOf('folder.gif') != -1); \n" +
            "  } \n" +
            "</script>\n";

        public ReportGeneratorWebPart(){                                                        
            this.PreRender += new EventHandler(WebPart_ClientScript_PreRender);          
        }                                                                                
        private void WebPart_ClientScript_PreRender(object sender , System.EventArgs e ) 
        {
            if (!isLicensed)
                return;

            if (!Page.IsClientScriptBlockRegistered(filterIncludeScriptKey))
            {
                Page.RegisterClientScriptBlock(filterIncludeScriptKey,
                EmbeddedScriptFormat_itemClick);
            }                                 
        }                                                                                

        private enum ReportFormat
        {
            DOCX,
            SML,
            PDF,
            PPTX,
            RTF,
            WML,
            XLS,
            XLSX,
            HTML
        }
        const int MAX_NUMBER_VARIABLES = 20;
        #endregion
        protected override void  OnPreRender(EventArgs e)
        {
            base.OnPreRender(e);

            if (log.IsDebugEnabled)
              log.Debug("Handling prerender");

            if (!isLicensed)
              return;
        }
        protected override void CreateChildControls()
        {
            base.CreateChildControls();

            if (log.IsDebugEnabled)
                log.Debug("creating child controls");

            try
            {
                // read in license from web.config
                ArrowUtils.InitializeArrow(string.Concat(Page.Request.PhysicalApplicationPath, "\\web.config"));
                isLicensed = true;
            }
            catch (LicenseException lex)
            {
                ArrowUtils.LogFatalException(log, lex);
                Controls.Add(new LiteralControl(string.Format("License Error: {0}", lex.Message)));
                return;
            }

            try
            {
                wizzy = new Wizard();
                wizzy.Width = 550;//725;
                wizzy.Height = 400;// 362;
                wizzy.StepStyle.VerticalAlign = VerticalAlign.Top;
                wizzy.BorderStyle = BorderStyle.Solid;
                wizzy.BorderColor = Color.FromName("Black");
                wizzy.BorderWidth = 1;
                wizzy.SideBarStyle.Width = 150;
                wizzy.SideBarStyle.VerticalAlign = VerticalAlign.Top;
                wizzy.NextButtonClick += wizzy_NextButtonClick;
                wizzy.FinishButtonClick += wizzy_FinishButtonClick;
                wizzy.DisplaySideBar = false;

                Button tempButton = (Button)wizzy.FindControl("StepNavigationTemplateContainerID$StepNextButton");
                tempButton.ValidationGroup = String.Format("validationGroup{0}", this.UniqueID);
                tempButton.CausesValidation = true;

                for (int i = 0; i < 5; i++)
                {
                    WizardStepBase newStep = new WizardStep();
                    newStep.ID = "Step" + (i).ToString();
                    newStep.Title = "Step" + (i).ToString();

                    newStep.Controls.Add(createTable(i));

                    wizzy.WizardSteps.Add(newStep);
                }
                Controls.Add(wizzy);
            }
            catch (Exception ex)
            {
                ArrowUtils.LogFatalException(log, ex);
                Controls.Clear();
                Controls.Add(new LiteralControl(string.Format("There was an error creating the report generator web part: {0}", ex.Message)));
                return;
            }
        }
        #region tab Creation Functions

        /// <summary>
        /// Review step.
        /// </summary>
        /// <param name="headerStyle"></param>
        /// <param name="normalStyle"></param>
        /// <param name="normalBoldStyle"></param>
        /// <returns></returns>
        private Table createStep4Tab(Style headerStyle, Style normalStyle, Style normalBoldStyle)
        {
            if (log.IsDebugEnabled)
                log.Debug("Creating step 4.");

            Table step4Table = createEmptyTable(10, 1, 41, 142);

            ASPxLabel step4Header = new ASPxLabel();
            step4Header.Text = "Step 4: Review details and generate the report/URL";
            step4Header.ApplyStyle(headerStyle);

            ASPxLabel step4First = new ASPxLabel();
            step4First.Text = "Template/Report definition file: \n";
            step4First.ApplyStyle(normalBoldStyle);

            ASPxLabel step4Second = new ASPxLabel();
            step4Second.Text = "Variables \n\n";
            step4Second.ApplyStyle(normalBoldStyle);

            GridViewDataTextColumn varNames = new GridViewDataTextColumn { Caption = "Variable Name", FieldName = "VariableName" };
            GridViewDataTextColumn required = new GridViewDataTextColumn { Caption = "Required", FieldName = "Required" };
            GridViewDataTextColumn type = new GridViewDataTextColumn { Caption = "Type", FieldName = "Type" };
            GridViewDataTextColumn value = new GridViewDataTextColumn { Caption = "Specify a Value", FieldName = "Value" };
            
            variableFinalList = new ASPxGridView();
            variableFinalList.Columns.Add(varNames);
            variableFinalList.Columns.Add(required);
            variableFinalList.Columns.Add(type);
            variableFinalList.Columns.Add(value);
            variableFinalList.KeyFieldName = "VariableName";
            variableFinalList.Width = Unit.Percentage(100);

            ASPxLabel step4Third = new ASPxLabel { Text = "Report format: \n" };
            step4Third.ApplyStyle(normalBoldStyle);

            ASPxLabel step4Fourth = new ASPxLabel { Text = "Report name: \n" };
            step4Fourth.ApplyStyle(normalBoldStyle);

            ASPxLabel step4Fifth = new ASPxLabel { Text = "Output destination: \n" };
            step4Fifth.ApplyStyle(normalBoldStyle);

            finalLiteral = new LiteralControl();
            finalLiteral.Visible = false;
            finalStatus = new ASPxLabel();
            finalStatus.ApplyStyle(normalStyle);
            finalStatus.ClientVisible = false;

            step4Table.Rows[0].Cells[0].HorizontalAlign = HorizontalAlign.Center;
            step4Table.Rows[1].Cells[0].Controls.Add(step4Header);
            step4Table.Rows[2].Cells[0].HorizontalAlign = HorizontalAlign.Center;
            step4Table.Rows[3].Cells[0].HorizontalAlign = HorizontalAlign.Center;
            step4Table.Rows[4].Cells[0].HorizontalAlign = HorizontalAlign.Center;
            step4Table.Rows[5].Cells[0].HorizontalAlign = HorizontalAlign.Center;
            step4Table.Rows[6].Cells[0].HorizontalAlign = HorizontalAlign.Center;
            step4Table.Rows[7].Cells[0].HorizontalAlign = HorizontalAlign.Center;
            step4Table.Rows[8].Cells[0].HorizontalAlign = HorizontalAlign.Center;
            step4Table.Rows[9].Cells[0].HorizontalAlign = HorizontalAlign.Center;

            //add labels
            step4Table.Rows[2].Cells[0].Controls.Add(step4First);
            step4Table.Rows[3].Cells[0].Controls.Add(step4Third);
            step4Table.Rows[4].Cells[0].Controls.Add(step4Fourth);
            step4Table.Rows[5].Cells[0].Controls.Add(step4Fifth);

            template_val = new ASPxLabel();
            template_val.ApplyStyle(normalStyle);
            reportName_val = new ASPxLabel();
            reportName_val.ApplyStyle(normalStyle);
            reportFormat_val = new ASPxLabel();
            reportFormat_val.ApplyStyle(normalStyle);
            outputDestination_val = new ASPxLabel();
            outputDestination_val.ApplyStyle(normalStyle);

            reportName_val.Text = ArrowUtils.htmlEncode((string)ViewState[VS_RPT_NAME]);
            reportFormat_val.Text = ArrowUtils.htmlEncode((string)ViewState[VS_OUT_FORMT]);
            template_val.Text = ArrowUtils.htmlEncode((string)ViewState[VS_TEMPL_NAME]);
            outputDestination_val.Text = (string)ViewState[VS_OUT_DEST];

            //add fields
            step4Table.Rows[2].Cells[0].Controls.Add(template_val);
            step4Table.Rows[3].Cells[0].Controls.Add(reportFormat_val);
            step4Table.Rows[4].Cells[0].Controls.Add(reportName_val);
            step4Table.Rows[5].Cells[0].Controls.Add(outputDestination_val);
            step4Table.Rows[7].Cells[0].Controls.Add(finalStatus);
            step4Table.Rows[8].Cells[0].Controls.Add(finalLiteral);

            if (log.IsDebugEnabled)
                log.Debug("Finished creating step 4.");

            return step4Table;
        }

        /// <summary>
        /// Output selection step.
        /// </summary>
        /// <param name="headerStyle"></param>
        /// <param name="normalStyle"></param>
        /// <param name="normalBoldStyle"></param>
        /// <returns></returns>
        private Table createStep3Tab(Style headerStyle, Style normalStyle, Style normalBoldStyle)
        {
            if (log.IsDebugEnabled)
                log.Debug("Creating step 3.");

            // create step header label
            ASPxLabel step3Header = new ASPxLabel();
            step3Header.Text = "Step 3: Set report name, whether to generate a document or URL, and the report format.\n\t ";
            step3Header.ApplyStyle(headerStyle);

            // error message label
            Style errorStyle = new Style();
            errorStyle.Font.Name = "Verdana";
            errorStyle.Font.Size = FontUnit.Parse("12pt");
            errorStyle.Font.Bold = true;
            errorMessage_step3 = new ASPxLabel();
            errorMessage_step3.ClientVisible = false;
            errorMessage_step3.Text = "";
            errorMessage_step3.ApplyStyle(errorStyle);
            errorMessage_step3.ForeColor = System.Drawing.Color.Red;

            // substep-number column labels
            ASPxLabel one = new ASPxLabel { Text = "1." };
            one.ApplyStyle(normalStyle);
            ASPxLabel two = new ASPxLabel { Text = "2." };
            two.ApplyStyle(normalStyle);
            ASPxLabel four = new ASPxLabel { Text = "4." };
            four.ApplyStyle(normalStyle);
            three = new ASPxLabel { Text = "3." };
            three.ApplyStyle(normalStyle);

            // report name label
            ASPxLabel reportNameLabel = new ASPxLabel();
            reportNameLabel.Text = "Report name:";
            reportNameLabel.ApplyStyle(normalStyle);

            // report name text box
            reportName = new ASPxTextBox();
            reportName.Width = ArrowUtils.DEFAULT_TXTBX_WIDTH;
            reportName.NullText = "";
            if (ViewState[VS_RPT_NAME] != null && ((string)ViewState[VS_RPT_NAME]).Length > 0)
            {
                reportName.Text = (string)ViewState[VS_RPT_NAME];
            }
            reportName.ValueChanged += reportName_ValueChanged;

            // output type label
            ASPxLabel outputTypeLabel = new ASPxLabel();
            outputTypeLabel.Text = "Select how you would like the report generated." +
                                "\n\t A report can be created from a Sharepoint web address (URL), \n or saved to a document library.";
            outputTypeLabel.ApplyStyle(normalStyle);

            // output type radio button menu
            ASPxRadioButton genUrl = new ASPxRadioButton();
            genUrl.Text = "Generate a URL";
            genUrl.GroupName = "typeSelect";
            genUrl.ID = "url";
            genUrl.AutoPostBack = true;
            genUrl.ValueChanged += radio_valueChanged;
            ASPxRadioButton report = new ASPxRadioButton();
            report.Text = "Document library";
            report.GroupName = "typeSelect";
            report.ID = "report";
            report.AutoPostBack = true;
            report.ValueChanged += radio_valueChanged;

            // output folder selector label
            selDocLibLabel = new ASPxLabel();
            selDocLibLabel.Text = "Select a document library folder: \n";
            selDocLibLabel.ClientVisible = false;
            three.ClientVisible = false;
            selDocLibLabel.ApplyStyle(normalStyle);

            // output folder selector
            outputFolderSelector = new SPFileSelector(SPFileSelector.Mode.Folder);
            outputFolderSelector.Visible = false;

            // output format menu label
            ASPxLabel outputFormatLabel = new ASPxLabel();
            outputFormatLabel.Text = "Select the report format.";
            outputFormatLabel.ApplyStyle(normalStyle);

            // get the output format images
            formatImages = getValidOutputImages();

            // layout tables
            Table step3Table = createEmptyTable(2, 1, 41, 150);
            Table headerTable = createEmptyTable(2, 2, 41, 150);
            Table outputFormatImageTable = createEmptyTable(3, 7, 41, 150);
            Table t3 = createEmptyTable(9, 3, 41, 152);

            step3Table.Rows[0].Cells[0].Controls.Add(headerTable);
            step3Table.Rows[1].Cells[0].Controls.Add(t3);

            headerTable.Rows[0].Cells[1].Controls.Add(step3Header);
            headerTable.Rows[1].Cells[1].Controls.Add(errorMessage_step3);

            t3.Rows[0].Cells[0].Controls.Add(one);
            t3.Rows[0].Cells[1].Controls.Add(reportNameLabel);
            t3.Rows[1].Cells[1].Controls.Add(reportName);
            t3.Rows[2].Cells[0].Controls.Add(two);
            t3.Rows[2].Cells[1].Controls.Add(outputTypeLabel);
            t3.Rows[3].Cells[1].Controls.Add(genUrl);
            t3.Rows[3].Cells[1].Controls.Add(report);
            t3.Rows[4].Cells[0].Controls.Add(three);
            t3.Rows[4].Cells[1].Controls.Add(selDocLibLabel);
            t3.Rows[5].Cells[1].Controls.Add(outputFolderSelector);
            t3.Rows[6].Cells[0].Controls.Add(four);
            t3.Rows[6].Cells[1].Controls.Add(outputFormatLabel);
            t3.Rows[7].Cells[1].Controls.Add(outputFormatImageTable);

            // output format menu buttons
            docxButton = new ASPxButton { ID = RPT_DOCX };
            docxButton.CheckedChanged += outputButton_CheckedChanged;
            xlsxButton = new ASPxButton { ID = RPT_XLSX };
            xlsxButton.CheckedChanged += outputButton_CheckedChanged;
            pptxButton = new ASPxButton { ID = RPT_PPTX };
            pptxButton.CheckedChanged += outputButton_CheckedChanged;
            pdfButton = new ASPxButton { ID = RPT_PDF };
            pdfButton.CheckedChanged += outputButton_CheckedChanged;
            htmlButton = new ASPxButton { ID = RPT_HTML };
            htmlButton.CheckedChanged += outputButton_CheckedChanged;
            xmlButton = new ASPxButton { ID = RPT_WML };
            xmlButton.CheckedChanged += outputButton_CheckedChanged;
            rtfButton = new ASPxButton { ID = RPT_RTF };
            rtfButton.CheckedChanged += outputButton_CheckedChanged;
            smlButton = new ASPxButton { ID = RPT_SML };
            smlButton.CheckedChanged += outputButton_CheckedChanged;
            xlsButton = new ASPxButton { ID = RPT_XLS };
            xlsButton.CheckedChanged += outputButton_CheckedChanged;

            docxButton.GroupName = "outputFormats";
            xlsxButton.GroupName = "outputFormats";
            pptxButton.GroupName = "outputFormats";
            pdfButton.GroupName = "outputFormats";
            htmlButton.GroupName = "outputFormats";
            xmlButton.GroupName = "outputFormats";
            rtfButton.GroupName = "outputFormats";
            smlButton.GroupName = "outputFormats";
            xlsButton.GroupName = "outputFormats";

            docxButton.ImageUrl = imageDir + "docxIcon.png";
            xlsxButton.ImageUrl = imageDir + "xlsxIcon.png";
            pptxButton.ImageUrl = imageDir + "pptxIcon.png";
            pdfButton.ImageUrl = imageDir + "pdfIcon.png";
            xmlButton.ImageUrl = imageDir + "wordmlIcon.png";
            rtfButton.ImageUrl = imageDir + "rtfIcon.png";
            smlButton.ImageUrl = imageDir + "smlIcon.png";
            xlsButton.ImageUrl = imageDir + "xlsIcon.png";
            htmlButton.ImageUrl = imageDir + "htmlIcon.png";

            // build the output format image table
            string pptx = "pptx";
            if (pptx.Equals(ViewState[VS_TEMPL_EXT]))
            {
                outputFormatImageTable.Rows[0].Cells[4].Controls.Add(pptxButton);
                outputFormatImageTable.Rows[0].Cells[3].Controls.Add(pdfButton);
            }
            else
            {
                outputFormatImageTable.Rows[0].Cells[0].Controls.Add(docxButton);
                outputFormatImageTable.Rows[0].Cells[1].Controls.Add(xlsxButton);
                outputFormatImageTable.Rows[0].Cells[2].Controls.Add(htmlButton);
                outputFormatImageTable.Rows[0].Cells[3].Controls.Add(pdfButton);
                outputFormatImageTable.Rows[1].Cells[0].Controls.Add(xmlButton);
                outputFormatImageTable.Rows[1].Cells[1].Controls.Add(xlsButton);
                outputFormatImageTable.Rows[1].Cells[2].Controls.Add(smlButton);
                outputFormatImageTable.Rows[1].Cells[3].Controls.Add(rtfButton);
            }

            if (log.IsDebugEnabled)
                log.Debug("Finished creating step 3.");

            return step3Table;
        }

        /// <summary>
        /// Variable selection step.
        /// </summary>
        /// <param name="headerStyle"></param>
        /// <returns></returns>
        private Table createStep2Tab(Style headerStyle)
        {
            if (log.IsDebugEnabled)
                log.Debug("Creating step 2.");

            ASPxLabel step2Header = new ASPxLabel();
            step2Header.Text = "Step 2: Set the values for the following variables." +
                                "These values will be used inside the template at runtime.";
            step2Header.ApplyStyle(headerStyle);
            step2Header.Width = Unit.Pixel(700);

            Style errorStyle = new Style();
            errorStyle.Font.Name = "Verdana";
            errorStyle.Font.Size = FontUnit.Parse("12pt");
            errorStyle.Font.Bold = true;

            errorMessage_step2 = new ASPxLabel();
            errorMessage_step2.Text = "";
            errorMessage_step2.ClientVisible = false;
            errorMessage_step2.ApplyStyle(errorStyle);
            errorMessage_step2.ForeColor = System.Drawing.Color.Red;

            Table step2Table = createEmptyTable(3,1,41,150);
            step2Table.Rows[0].Cells[0].Controls.Add(step2Header);
            step2Table.Rows[1].Cells[0].Controls.Add(errorMessage_step2);
            step2Table.Rows[2].Cells[0].Controls.Add(createTable1(headerStyle));

            if (log.IsDebugEnabled)
                log.Debug("Finished creating step 2.");

            return step2Table;
        }

        /// <summary>
        /// Template/report def selection step.
        /// </summary>
        /// <param name="headerStyle"></param>
        /// <param name="normalStyle"></param>
        /// <param name="normalBoldStyle"></param>
        /// <returns></returns>
        private Table createStep1Tab(Style headerStyle, Style normalStyle, Style normalBoldStyle)
        {
            if (log.IsDebugEnabled)
                log.Debug("Creating step 1.");

            // create step header label
            ASPxLabel step1Header = new ASPxLabel();
            step1Header.Text = "Step 1: Pick a template or report definition";
            step1Header.ApplyStyle(headerStyle);

            // select library instructions label
            ASPxLabel lblSelectLib = new ASPxLabel();
            lblSelectLib.Text = "1. Select the template or report definition: \n";
            lblSelectLib.ApplyStyle(normalStyle);
            
            // create report def file selector
            rptDefFileSelector = new SPFileSelector(SPFileSelector.Mode.File);

            // create error message label
            Style errorStyle = new Style();
            errorStyle.Font.Name = "Verdana";
            errorStyle.Font.Size = FontUnit.Parse("12pt");
            errorStyle.Font.Bold = true;
            errorMessage_step1 = new ASPxLabel();
            errorMessage_step1.ClientVisible = false;
            errorMessage_step1.Text = "";
            errorMessage_step1.ApplyStyle(errorStyle);
            errorMessage_step1.ForeColor = System.Drawing.Color.Red;

            // add controls to layout table
            Table t1 = createEmptyTable(4, 2, 41, 125);
            t1.Rows[0].Cells[1].Controls.Add(step1Header);
            t1.Rows[1].Cells[1].Controls.Add(errorMessage_step1);
            t1.Rows[1].Height = new Unit(0);
            t1.Rows[2].Cells[1].Controls.Add(lblSelectLib);
            t1.Rows[3].Cells[1].Controls.Add(rptDefFileSelector);

            if (log.IsDebugEnabled)
                log.Debug("Finished creating step 1.");

            // return layout table
            return t1;
        }

        private Table createOverviewTab(Style normalStyle, Style normalBoldStyle)
        {
            if (log.IsDebugEnabled)
                log.Debug("Creating overview tab.");

            ASPxLabel s1 = new ASPxLabel();
            ASPxLabel s2 = new ASPxLabel();
            ASPxLabel s3 = new ASPxLabel();
            ASPxLabel s4 = new ASPxLabel();
            s1.ApplyStyle(normalBoldStyle);
            s2.ApplyStyle(normalBoldStyle);
            s3.ApplyStyle(normalBoldStyle);
            s4.ApplyStyle(normalBoldStyle);

            s1.Text = "Step 1:";
            s2.Text = "Step 2:";
            s3.Text = "Step 3:";
            s4.Text = "Finalize\nand\nGo:  ";

            ASPxImage templateStep = new ASPxImage();
            ASPxImage dataStep = new ASPxImage();
            ASPxImage outputStep = new ASPxImage();
            ASPxImage reviewStep = new ASPxImage();

            ASPxLabel templateOv = new ASPxLabel();
            ASPxLabel dataOv = new ASPxLabel();
            ASPxLabel outputOv = new ASPxLabel();
            ASPxLabel reviewOv = new ASPxLabel();
            templateOv.ApplyStyle(normalStyle);
            outputOv.ApplyStyle(normalStyle);
            reviewOv.ApplyStyle(normalStyle);
            dataOv.ApplyStyle(normalStyle);

            templateOv.Width = Unit.Pixel(700);
            dataOv.Width = Unit.Pixel(700);
            outputOv.Width = Unit.Pixel(700);
            reviewOv.Width = Unit.Pixel(700);

            templateOv.Text = "Pick a template or report definition file. Template files can be" +
                              " in the following formats: docx, rtf, xls, xlsx, pptx, and" +
                              " .xml (wordML, spreadsheetML only).";
            dataOv.Text = "Set runtime variables; these will be passed into the template.";
            outputOv.Text = "Select the output format and save destination. Valid output formats can" +
                              " be one of the following: docx, doc, rtf, txt, html, pdf, xls, xlsx, " +
                              "pptx. The output can be a report saved to a document library or" +
                              " a web address (URL).";
            reviewOv.Text = "Review all of the details from each step before generating the report.";

            templateStep.ImageUrl = templateImage;
            dataStep.ImageUrl = variableImage;
            outputStep.ImageUrl = outputImage;
            reviewStep.ImageUrl = reviewImage;

            Table overviewTable = createEmptyTable(9, 3, 40, 142);

            overviewTable.Rows[1].Cells[0].VerticalAlign = VerticalAlign.Top;
            overviewTable.Rows[3].Cells[0].VerticalAlign = VerticalAlign.Top;
            overviewTable.Rows[5].Cells[0].VerticalAlign = VerticalAlign.Top;
            overviewTable.Rows[7].Cells[0].VerticalAlign = VerticalAlign.Top;

            overviewTable.Rows[1].Cells[1].VerticalAlign = VerticalAlign.Top;
            overviewTable.Rows[3].Cells[1].VerticalAlign = VerticalAlign.Top;
            overviewTable.Rows[5].Cells[1].VerticalAlign = VerticalAlign.Top;
            overviewTable.Rows[7].Cells[1].VerticalAlign = VerticalAlign.Top;
            overviewTable.Rows[7].Cells[1].HorizontalAlign = HorizontalAlign.Center;

            //overviewTable.Rows[0].Cells[0].Controls.Add(new LiteralControl(String.Format("Site GUID = {0}", SPContext.Current.Site.ID)));
            overviewTable.Rows[1].Cells[0].Controls.Add(templateStep);
            overviewTable.Rows[3].Cells[0].Controls.Add(dataStep);
            overviewTable.Rows[5].Cells[0].Controls.Add(outputStep);
            overviewTable.Rows[7].Cells[0].Controls.Add(reviewStep);

            overviewTable.Rows[1].Cells[1].Controls.Add(s1);
            overviewTable.Rows[3].Cells[1].Controls.Add(s2);
            overviewTable.Rows[5].Cells[1].Controls.Add(s3);
            overviewTable.Rows[7].Cells[1].Controls.Add(s4);

            overviewTable.Rows[1].Cells[2].Controls.Add(templateOv);
            overviewTable.Rows[3].Cells[2].Controls.Add(dataOv);
            overviewTable.Rows[5].Cells[2].Controls.Add(outputOv);
            overviewTable.Rows[7].Cells[2].Controls.Add(reviewOv);

            if (log.IsDebugEnabled)
                log.Debug("Finished creating overview tab.");

            return overviewTable;
        }
        #endregion

        private ReportDefinition getRAIFromViewState()
        {
            string errorMessage = "";
            ReportDefinition rai = ArrowUtils.GetReportDefFromFile(new Guid((string)ViewState[VS_TEMPL_SITE_GUID]), 
                                                                   new Guid((string)ViewState[VS_TEMPL_GUID]),out errorMessage);
            return rai;
        }
        private DataDefinition[] getRDSIFromRAI(ReportDefinition rai)
        {
            return rai.getDataSources();
        }
        private void CreateDocOutputTypeMenu(ASPxMenu outputTypes)
        {
            DevExpress.Web.ASPxMenu.MenuItem root = new DevExpress.Web.ASPxMenu.MenuItem();
            root.Text = "Select an Output Format";
            addAllValidOutputFormats(root);
            outputTypes.Items.Add(root);
        }

        private void addAllValidOutputFormats(DevExpress.Web.ASPxMenu.MenuItem root)
        {
            ArrayList formats = getValidOutputFormats();
            for (int index = 0; index < formats.Count; index++)
            {
                DevExpress.Web.ASPxMenu.MenuItem toAdd = new DevExpress.Web.ASPxMenu.MenuItem();
                toAdd.Text = (String)formats[index];
                root.Items.Add(toAdd);
            }
        }

        private System.Collections.Generic.Dictionary<string, string> getValidOutputImages()
        {
            System.Collections.Generic.Dictionary<string, string> formatImages = new System.Collections.Generic.Dictionary<string, string>();
            formatImages.Add("docx", "http://farm4.static.flickr.com/3422/3987885663_3f0ae23631_o.png");
            formatImages.Add("doc", "http://farm4.static.flickr.com/3560/3988641828_16b1d25753_o.png");
            formatImages.Add("xlsx", "http://farm3.static.flickr.com/2458/3988642280_f769d06d17_o.png");
            formatImages.Add("xls", "http://farm3.static.flickr.com/2543/3988642134_b15907f57c_o.png");
            formatImages.Add("pptx", "http://farm3.static.flickr.com/2620/3987885875_4f9dc2c6c2_o.png");
            formatImages.Add("html", "http://farm4.static.flickr.com/3498/3987885773_b53281731f_o.png");
            formatImages.Add("txt", "http://farm4.static.flickr.com/3501/3987885591_1d5321acd7_o.png");
            formatImages.Add("rtf", "http://farm4.static.flickr.com/3434/3987885627_1ec70033e9_o.png");
            formatImages.Add("wordML", "http://farm3.static.flickr.com/2466/3988641742_f7d94bc6a6_o.png");
            formatImages.Add("pdf", "");
            return formatImages;
        }

        private static ArrayList getValidOutputFormats()
        {
            ArrayList formats = new ArrayList();
            formats.Add("docx");
            formats.Add("rtf");
            formats.Add("wordML");
            formats.Add("xls");
            formats.Add("xlsx");
            formats.Add("pptx");
            formats.Add("html");
            formats.Add("txt");
            formats.Add("pdf");
            return formats;
        }

        private void setOutputFormat()
        {
            string outputFormat = "";
            if (docxButton.Checked)
                outputFormat = docxButton.ID;
            else if(pptxButton.Checked)
                outputFormat = pptxButton.ID ;
            else if(xlsxButton.Checked)
                outputFormat = xlsxButton.ID;
            else if(xlsButton.Checked)
                outputFormat = xlsButton.ID;
            else if(htmlButton.Checked)
                outputFormat = htmlButton.ID;
            else if(xmlButton.Checked)
                outputFormat = xmlButton.ID;
            else if(smlButton.Checked)
                outputFormat = smlButton.ID;
            else if(rtfButton.Checked)
                outputFormat = rtfButton.ID;
            else if(pdfButton.Checked)
                outputFormat = pdfButton.ID;
            ViewState[VS_OUT_FORMT] = outputFormat;
        }
        private string getTemplateExtension(string template)
        {
            string ext = template.Substring((template.LastIndexOf(".")) + 1);
            return ext.ToLower();
        }
        
        #region delegate functions
        /// <summary>
        /// <para>Must set:</para>
        /// <para>ViewState[VS_OUT_DEST]</para>
        /// <para>ViewState[VS_OUT_DOC_LIB_GUID]</para>
        /// </summary>
        /// <returns></returns>
        bool isValidOutputDestination()
        {
            if ("URL".Equals((string)ViewState[VS_OUT_DEST]) || (string)ViewState[VS_OUT_DOC_LIB_GUID] != null)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        /// <summary>
        /// <para>Must set:</para>
        /// <para>ViewState[VS_RPT_NAME]</para>
        /// <para>ViewState[VS_OUT_FORMT]</para>
        /// <para>ViewState[VS_OUT_DEST]</para>
        /// <para>ViewState[VS_OUT_DOC_LIB_GUID]</para>
        /// </summary>
        /// <returns></returns>
        bool isStep3Valid(SPFileSelectorFolderInfo outFolderInfo)
        {
            bool isValid;
            String errormsg = "Error:\n";
            bool isValidReportName = ArrowUtils.ValidateReportName((string)ViewState[VS_RPT_NAME]);
            if (isValidReportName && (string)ViewState[VS_OUT_FORMT] != null
                && isValidOutputDestination())
            {
                errormsg = "";
                isValid = true;
            }
            else
            {
                if (!isValidReportName)
                    errormsg += "Invalid filename.\n";
                if (!outFolderInfo.IsSPFolder && !string.IsNullOrEmpty(outFolderInfo.Url))
                {
                    errormsg += "Invalid save location. The selected directory is a website.\n";
                }
                errormsg += "Not all of the necessary fields are filled out. Make sure the title, save location, and report format are set.\n";
                errorMessage_step3.ClientVisible = true;
                isValid = false;
            }
            if ("HTML".Equals(ViewState[VS_OUT_FORMT]) && !(ViewState[VS_OUT_DEST].Equals("URL")))
            {
                //If report format is HTML and going to a doc lib, inform user this is not possible at the moment
                errormsg +=
                    "Outputting to HTML into a document library is currently not supported; try another format or choose 'Create a URL' instead.";
                isValid = false;
                errorMessage_step3.ClientVisible = true;
            }
            errorMessage_step3.Text = errormsg;
            return isValid;
        }
        bool step2Validation(ReportDefinition rai, out string errorMessage)
        {
            int ind_WR_LOGIN = -1, ind_WR_USER = -1;
            for (int i = 0; i < rai.variableNameArray.Length; i++)
            {
                if (rai.variableNameArray[i].Equals("WR_LOGIN"))
                    ind_WR_LOGIN = i;
                else if (rai.variableNameArray[i].Equals("WR_USER"))
                    ind_WR_USER = i;
            }

            bool toReturn = true;
            errorMessage = "Error:";
            int raiVarInd = 0;
            for (int i = 0; i < ArrowUtils.GetNumVarsForDisplay(rai); i++)
            {
                while (raiVarInd == ind_WR_LOGIN || raiVarInd == ind_WR_USER)
                {
                    raiVarInd++;
                }
                if (raiVarInd >= rai.variableNameArray.Length)
                {
                    // this shouldn't happen
                    Trap.trap();
                    if (log.IsDebugEnabled)
                        log.Debug("raiVarInd >= rai.variableNameArray.Length returned true");
                }

                variableNameLabelArray[i].Text = rai.variableNameArray[raiVarInd];
                variableTypeLabelArray[i].Text = rai.variableTypeArray[raiVarInd];

                if (variableTypeLabelArray[i].Text.ToLower() == "select")
                {
                    //do select and add items;
                    string nameToSearch = rai.variableDataNameArray[raiVarInd];
                    DataDefinition[] datasources = rai.getDataSources();
                    DataDefinition dd = null;
                    for (int j = 0; j < rai.dataSourceNameArray.Length; j++)
                    {
                        if (rai.dataSourceNameArray[j] == nameToSearch)
                        {
                            dd = datasources[j];
                            break;
                        }
                    }
                    if (dd == null)
                        throw new FileNotFoundException(string.Format("Could not find datadef entry named {0}.", nameToSearch));
                    bool isVarValid;
                    if (dd.IsXml)
                    {
                        isVarValid = DataSourceHandlerBase.ValidateVariableXml(nameToSearch, dd.ConnectionString, dd.UserName, dd.Password,
                            rai.variableSelectValueArray[raiVarInd], rai.variableNameArray[raiVarInd], variableValueTextBoxArray[i].Text);
                    }
                    else
                    {
                        string vendorName = dd.VendorName ?? string.Empty;
                        string factoryClass = dd.FactoryClass ?? string.Empty;
                        isVarValid = DataSourceHandlerBase.ValidateVariableAdo(nameToSearch, dd.Description, dd.ConnectionString, vendorName, factoryClass, 
                            rai.variableSelectValueArray[raiVarInd], rai.variableNameArray[raiVarInd], variableValueTextBoxArray[i].Text);
                    }
                    if (!isVarValid)
                    {
                        errorMessage += "* Cannot validate value for the variable named: " + rai.variableNameArray[raiVarInd] + " ; try a different value.\n";
                        return false;
                    }
                }
                raiVarInd++;
            }
            return toReturn;
        }
        void outputTypes_itemClick(object sender, MenuItemEventArgs e)
        {
            if (log.IsDebugEnabled)
                log.Debug("handling output type item click");

            DevExpress.Web.ASPxMenu.MenuItem lib = (DevExpress.Web.ASPxMenu.MenuItem)e.Item;
            reportFormat_val.Text = lib.Text;
        }
        void reportName_ValueChanged(object o, EventArgs e)
        {
            if (log.IsDebugEnabled)
                log.Debug("handling report name changed");

            ASPxTextBox sender = (ASPxTextBox)o;
            ViewState[VS_RPT_NAME] = ArrowUtils.trim(sender.Text);
            HttpContext.Current.Cache["ReportName_Global"] = ArrowUtils.trim(sender.Text);
            
        }
        void radio_valueChanged(object o, EventArgs e)
        {
            if (log.IsDebugEnabled)
                log.Debug("handling radio value changed");

            ASPxRadioButton sender = (ASPxRadioButton)o;
            if (sender.Checked && sender.ID.Equals("url"))
            {
                selDocLibLabel.ClientVisible = false;
                three.ClientVisible = false;
                ViewState[VS_OUT_DEST] = "URL";
                outputDestination_val.Text = "URL";
                outputFolderSelector.Visible = false;
            }
            if (sender.Checked && sender.ID.Equals("report"))
            {
                outputFolderSelector.Visible = true;
                selDocLibLabel.ClientVisible = true;
                three.ClientVisible = true;
                ViewState[VS_OUT_DEST] = null;
            }
        }
        void outputButton_CheckedChanged(object o, EventArgs e)
        {
            if (log.IsDebugEnabled)
                log.Debug("handling output button checked changed");

            ASPxButton sender = (ASPxButton)o;
            if (sender.Checked)
            {
                ViewState[VS_OUT_FORMT] = sender.ID;
            }
        }
        void wizzy_NextButtonClick(object o, WizardNavigationEventArgs e)
        {
            if (log.IsDebugEnabled)
                log.Debug("handling next button click");

            if (e.CurrentStepIndex == 0)
            {
                if (log.IsDebugEnabled)
                    log.Debug("moving from step 0");

                //ArrowDefault defaults = ArrowCentralControl.getApplicableDefaultsForType(SPContext.Current.Site.ID.ToString(), 3);
                //if (defaults != null)
                //{
                //    ViewState[VS_TEMPL_LIB_GUID] = defaults.docLibGuid;
                //    ViewState[VS_TEMPL_SITE_GUID] = defaults.siteGuid;
                //    ViewState[VS_TEMPL_LIB_NAME] = ArrowUtils.getDocLibObject(defaults.siteGuid, defaults.docLibGuid).Title;
                //    doDocListGridBinding();
                //    step1Second.Visible = true;
                //    step1Second.ClientVisible = true;
                //}
            }
            else if (e.CurrentStepIndex == 1)
            {
                if (log.IsDebugEnabled)
                    log.Debug("moving from step 1");

                // get the selected file info
                SPFileSelectorFileInfo rptDefFileInfo = rptDefFileSelector.SelectedFile;
                if (rptDefFileInfo.IsAccessDenied)
                {
                    e.Cancel = true;
                    errorMessage_step1.Text = "You do not have permission to access the selected template or report definition.";
                    errorMessage_step1.ClientVisible = true;
                    return;
                }
                ViewState[VS_TEMPL_LIB_GUID] = rptDefFileInfo.LibGuid;
                ViewState[VS_TEMPL_GUID] = rptDefFileInfo.Guid;
                ViewState[VS_TEMPL_NAME] = rptDefFileInfo.Name;
                ViewState[VS_TEMPL_SITE_GUID] = rptDefFileInfo.WebGuid;

                //Set the template_val variable in the ViewState
                SPFile template = ArrowUtils.GetSPFile(rptDefFileInfo.Url);
                Guid templateGUID = template.UniqueId;
                template_val.Text = (string)ViewState[VS_TEMPL_NAME];

                // get the report definition object
                string errorMessage = "";
                ReportDefinition rai = null;
                try
                {
                    rai = ArrowUtils.GetReportDefFromFile(new Guid((string)ViewState[VS_TEMPL_SITE_GUID]),
                                                                   new Guid((string)ViewState[VS_TEMPL_GUID]), out errorMessage);
                }
                catch (Exception ex)
                {
                    if (errorMessage == null)
                        errorMessage = string.Empty;
                    errorMessage = string.Format("{0}\nThe template or report definition is invalid.\n{1}", errorMessage, ex.Message);
                }
                if (rai == null)
                {
                    e.Cancel = true;
                    errorMessage_step1.Text = errorMessage;
                    errorMessage_step1.ClientVisible = true;
                    return;
                }
                errorMessage_step1.ClientVisible = false;

                ViewState[VS_TEMPL_EXT] = getTemplateExtension(rai.template);

                if (ArrowUtils.GetNumVarsForDisplay(rai) <= 0)
                {
                    if (log.IsDebugEnabled)
                        log.Debug("no vars detected; moving to step 3");
                    wizzy.ActiveStepIndex = 3;
                    //setOutputDefault();
                    return;
                }
                // Get parameters
                //for (int i = rai.variableNameArray.Length; i < variableNameLabelArray.Length; i++)
                for (int i = 0; i < variableNameLabelArray.Length; i++)
                {
                    variableNameLabelArray[i].Visible = false;
                    variableRequiredLabelArray[i].Visible = false;
                    variableTypeLabelArray[i].Visible = false;
                    variableValueTextBoxArray[i].Visible = false;
                    variableValueDropDownListArray[i].Visible = false;
                }

                int ind_WR_LOGIN = -1, ind_WR_USER = -1;
                for (int i = 0; i < rai.variableNameArray.Length; i++)
                {
                    if (rai.variableNameArray[i].Equals("WR_LOGIN"))
                        ind_WR_LOGIN = i;
                    else if (rai.variableNameArray[i].Equals("WR_USER"))
                        ind_WR_USER = i;
                }

                int raiVarInd = 0;
                for (int i = 0; i < ArrowUtils.GetNumVarsForDisplay(rai); i++)
                {
                    while (raiVarInd == ind_WR_LOGIN || raiVarInd == ind_WR_USER)
                    {
                        raiVarInd++;
                    }
                    if (raiVarInd >= rai.variableNameArray.Length)
                    {
                        // this shouldn't happen
                        Trap.trap();
                        if (log.IsDebugEnabled)
                            log.Debug("raiVarInd >= rai.variableNameArray.Length returned true");
                    }

                    Dictionary<string, string> kpd;

                    // BEGIN Code for prepopulated variables from custom assembly
                    try
                    {
                        WindwardArrowConfigSection ArrowConfigSection;
                        if (HttpContext.Current == null)
                            ArrowConfigSection = ConfigurationManager.GetSection("WindwardArrow") as WindwardArrowConfigSection;
                        else
                            ArrowConfigSection = WebConfigurationManager.GetSection("WindwardArrow") as WindwardArrowConfigSection;
                        Assembly assembly = Assembly.Load(ArrowConfigSection.customAssembly);
                        Type t = Type.GetType(ArrowConfigSection.customAssemblyClass + "," + assembly.FullName);

                        object ap = Activator.CreateInstance(t);
                        object[] args = new object[4] { SPContext.Current.Web.CurrentUser.Name, rai.title, rai.template, rai.variableNameArray };
                        kpd = (Dictionary<string, string>)t.InvokeMember("setParameters", BindingFlags.InvokeMethod, null, ap, args);
                    }
                    catch
                    {
                        kpd = new Dictionary<string, string>();
                        kpd.Add("blah", "blah");
                        if (log.IsDebugEnabled)
                            log.Debug("caught unknown exception; added temp kpd to dictionary");
                    }
                    // END Code for prepopulated variables from custom assembly

                    string[] parameterKeys = new string[kpd.Count];
                    string[] parameterValues = new string[kpd.Count];
                    kpd.Keys.CopyTo(parameterKeys, 0);
                    kpd.Values.CopyTo(parameterValues, 0);
                    ViewState[VS_KPD_KEYS] = parameterKeys;
                    ViewState[VS_KPD_VALS] = parameterValues;

                    //if (!kpd.ContainsKey(rai.variableNameArray[i]))
                    //{
                    variableNameLabelArray[i].Visible = true;
                    variableNameLabelArray[i].Text = rai.variableNameArray[raiVarInd];

                    variableRequiredLabelArray[i].Visible = true;
                    variableRequiredLabelArray[i].Text = rai.variableRequiredArray[raiVarInd];

                    variableTypeLabelArray[i].Visible = true;
                    variableTypeLabelArray[i].Text = rai.variableTypeArray[raiVarInd];

                    if (variableTypeLabelArray[i].Text.ToLower() == "select")
                    {
                        
                        //do select and add items;
                        string nameToSearch = rai.variableDataNameArray[raiVarInd];
                        DataDefinition[] datasources = rai.getDataSources();
                        DataDefinition dataDef = null;
                        for (int j = 0; j < rai.dataSourceNameArray.Length; j++)
                        {
                            if (rai.dataSourceNameArray[j] == nameToSearch)
                            {
                                dataDef = datasources[j];
                                break;
                            }
                        }
                        if (dataDef == null)
                            throw new FileNotFoundException(string.Format("Could not find datadef entry named {0}.", nameToSearch));

                        object[][] queryResult = ArrowUtils.getSelectParameterObjects(rai.variableDataNameArray[raiVarInd], dataDef, rai.variableSelectCountArray[raiVarInd], rai.variableSelectAllArray[raiVarInd]);
                        if (queryResult.Length > 25)
                        {
                            //display a textbox instead of a drop down, do validatio on next button click
                            variableValueTextBoxArray[i].Visible = true;
                            variableValueTextBoxArray[i].Text = rai.variableDefaultArray[raiVarInd];
                        }
                        else
                        {
                            variableValueDropDownListArray[i].Visible = true;
                            foreach (object[] ob in queryResult)
                            {
                                string input = ob[0].ToString();
                                variableValueDropDownListArray[i].Items.Add(new ListItem(input, input));
                            }
                            if (variableValueDropDownListArray[i].Items.Count == 0)
                            {
                                variableValueDropDownListArray[i].Items.Add(new ListItem("<none>", ""));
                            }
                            //set default value
                            string defaultValue = rai.variableDefaultArray[raiVarInd];
                            for (int j = 0; j < variableValueDropDownListArray[i].Items.Count; j++)
                            {
                                if (variableValueDropDownListArray[i].Items[j].Value == defaultValue)
                                {
                                    variableValueDropDownListArray[i].SelectedIndex = j;
                                    break;
                                }
                            }
                        }
                    }
                    else // if the variable type is not "select"...
                    {
                        variableValueTextBoxArray[i].Visible = true;
                        if (!kpd.ContainsKey(rai.variableNameArray[raiVarInd]))
                            variableValueTextBoxArray[i].Text = rai.variableDefaultArray[raiVarInd];
                        else
                        {
                            string prePopulatedValue;
                            if (kpd.TryGetValue(rai.variableNameArray[raiVarInd], out prePopulatedValue))
                            {
                                variableValueTextBoxArray[i].Text = prePopulatedValue;
                            }
                            else
                                variableValueTextBoxArray[i].Text = rai.variableDefaultArray[raiVarInd];
                        }
                    }
                    if ("True".Equals(rai.variableHiddenArray[raiVarInd]))
                    {
                        variableTypeLabelArray[i].Visible = false;
                        variableValueDropDownListArray[i].Visible = false;
                        variableValueTextBoxArray[i].Visible = false;
                        variableNameLabelArray[i].Visible = false;
                        variableRequiredLabelArray[i].Visible = false;
                        variableNameLabelArray[i].Visible = false;
                    }

                    raiVarInd++;
                }

            }
            else if (e.CurrentStepIndex == 2)
            {
                if (log.IsDebugEnabled)
                    log.Debug("moving from step 2");

                errorMessage_step2.ClientVisible = false;
                string errorMessage;
                ReportDefinition rai = ArrowUtils.GetReportDefFromFile(new Guid((string)ViewState[VS_TEMPL_SITE_GUID]),
                                                   new Guid((string)ViewState[VS_TEMPL_GUID]), out errorMessage);
                if (!step2Validation(rai,out errorMessage))
                {
                    errorMessage_step2.Text = errorMessage;
                    errorMessage_step2.ClientVisible = true;
                    e.Cancel = true;
                    return;
                }
                //setOutputDefault();
            }
            else if (e.CurrentStepIndex == 3)
            {
                if (log.IsDebugEnabled)
                    log.Debug("moving from step 3");

                // load report name
                ViewState[VS_RPT_NAME] = ArrowUtils.trim(reportName.Text);
                reportName_val.Text = (string)ViewState[VS_RPT_NAME];

                // get selected output folder info
                SPFileSelectorFolderInfo outFolderInfo = outputFolderSelector.SelectedFolder;
                if (!"URL".Equals(ViewState[VS_OUT_DEST]))
                {
                    ViewState[VS_OUT_DOC_LIB_GUID] = outFolderInfo.LibGuid;
                    ViewState[VS_OUT_FOLDR_GUID] = outFolderInfo.Guid;
                    ViewState[VS_OUT_SITE_GUID] = outFolderInfo.WebGuid;
                    //String selectionMessage = web.Title + " -> " + docLib.Title;
                    //ViewState[VS_OUT_DEST] = selectionMessage;
                    ViewState[VS_OUT_DEST] = ArrowUtils.BuildFolderPathDisplayString(outFolderInfo);
                    outputDestination_val.Text = (string)ViewState[VS_OUT_DEST];
                }

                // validation
                if (!isStep3Valid(outFolderInfo))
                {
                    e.Cancel = true;
                    return;
                }
                //setOutputFormat();
            }
        }

        //private void setOutputDefault()
        //{
        //    ArrowDefault defaults = ArrowCentralControl.getApplicableDefaultsForType(SPContext.Current.Site.ID.ToString(), 2);
        //    if (defaults != null)
        //    {
        //        ViewState[VS_OUT_DOC_LIB_GUID] = defaults.docLibGuid;
        //        ViewState[VS_OUT_SITE_GUID] = defaults.siteGuid;

        //        String selectionMessage = ArrowUtils.getSPWeb(defaults.siteGuid).Title + " -> "
        //                                + ArrowUtils.getDocLibObject(defaults.siteGuid, defaults.docLibGuid).Title;
        //        ViewState[VS_OUT_DEST] = selectionMessage;
        //        outputDestination_val.Text = selectionMessage;
        //        DocLibSelection.Text = selectionMessage;

        //        Style headerStyle = new Style();
        //        headerStyle.Font.Name = "Verdana";
        //        headerStyle.Font.Size = FontUnit.Parse("12pt");

        //        DocLibSelection.ApplyStyle(headerStyle);
        //    }
        //}
        
        void wizzy_FinishButtonClick(object o, WizardNavigationEventArgs e)
        {
            if (log.IsDebugEnabled)
                log.Debug("handling finish button click");

            ReportDefinition rai = getRAIFromViewState();
            DataDefinition[] rdsi = getRDSIFromRAI(rai);
            Guid templateWebGuid = new Guid((string)ViewState[VS_TEMPL_SITE_GUID]);
            Guid templateGuid = new Guid((string)ViewState[VS_TEMPL_GUID]);
            SPFile template = ArrowUtils.GetSPFileFromSPWeb(templateWebGuid, templateGuid);
            string templateAbsPath = ArrowUtils.getAbsPathFromSPFile(template);

            string[] varValues = createVariableValuesArray(rai, variableValueTextBoxArray, variableValueDropDownListArray);
            string reportDisplayUrl;
            //if (((string)ViewState[VS_OUT_DEST]).Equals("URL"))
            if ("URL".Equals((string)ViewState[VS_OUT_DEST]))
            {
                //Generate a URL 
                string reportUrl = ArrowUtils.generateUrl(SPContext.Current.Web.Url, rai, templateAbsPath, (string)ViewState[VS_OUT_FORMT], varValues, (string)ViewState[VS_RPT_NAME]);
                reportDisplayUrl = ArrowUtils.makeURL("Report URL link", reportUrl);
            }
            else
            {
                //Generate a Report
                SPDocumentLibrary outDocLib = ArrowUtils.getDocLibObject((string)ViewState[VS_OUT_SITE_GUID], (string)ViewState[VS_OUT_DOC_LIB_GUID]);
                Guid outWebGuid = new Guid((string)ViewState[VS_OUT_SITE_GUID]);
                SPWeb outWeb = ArrowUtils.GetSPWebCollectionFromCurrentSite()[outWebGuid];
                string sFolderOutGuid = (string)ViewState[VS_OUT_FOLDR_GUID];
                SPFolder outFolder = null;
                if (!string.IsNullOrEmpty(sFolderOutGuid))
                {
                    Guid outFolderGuid = new Guid(sFolderOutGuid);
                    outFolder = outWeb.GetFolder(outFolderGuid);
                }

                string reportPath = ArrowUtils.generateReport(rai, rdsi, outDocLib, (string)ViewState[VS_RPT_NAME], (string)ViewState[VS_OUT_FORMT], varValues, outFolder);
                reportDisplayUrl = ArrowUtils.makeURL("Link to report in document library", reportPath);
            }

            finalLiteral.Text = reportDisplayUrl;
            finalLiteral.Visible = true;
            finalStatus.ClientVisible = true;
        }

        #endregion

        #region delegate function helper functions

        private string[] createVariableValuesArray(ReportDefinition rai, TextBox[] variableValueTextBoxArray, DropDownList[] variableValueDropDownListArray)
        {
            int numVars = ArrowUtils.GetNumVarsForDisplay(rai);

            string[] variableValues = new string[numVars];

            for (int i = 0; i < numVars; i++)
            {
                if (variableValueDropDownListArray[i].SelectedValue != null && variableValueDropDownListArray[i].SelectedValue.Length > 0)
                    variableValues[i] = variableValueDropDownListArray[i].SelectedValue.ToString();
                else
                    variableValues[i] = variableValueTextBoxArray[i].Text;
            }
            return variableValues;
        }

        #endregion
        #region table creation functions

        
        private Table createTable1(Style headerStyle)
        {
            //SPWeb site = SPContext.Current.Web;

            Style varStyle = new Style();
            varStyle.Font.Name = "Verdana";
            varStyle.Font.Size = FontUnit.Parse("12pt");
            varStyle.Font.Bold = true;

            ASPxLabel varName = new ASPxLabel();
            varName.Text = "Variable name         ";
            varName.ApplyStyle(varStyle);
            varName.Width = Unit.Pixel(200);
            ASPxLabel required = new ASPxLabel();
            required.Text = "Required ?     ";
            required.ApplyStyle(varStyle);
            required.Width = Unit.Pixel(180);
            ASPxLabel type = new ASPxLabel();
            type.Text = "Type    ";
            type.ApplyStyle(varStyle);
            type.Width = Unit.Pixel(150);
            ASPxLabel variableVal = new ASPxLabel();
            variableVal.Text = "Variable value    ";
            variableVal.ApplyStyle(varStyle);
            variableVal.Width = Unit.Pixel(150);


            Table t = createEmptyTableStatic(3 + MAX_NUMBER_VARIABLES, 4, 30, 800); // 41 -> 0
            t.Visible = true;

            //t.Rows[0].Cells[0].Controls.Add();

            t.Rows[1].Cells[0].Controls.Add(varName);
            t.Rows[1].Cells[1].Controls.Add(required);
            t.Rows[1].Cells[2].Controls.Add(type);
            t.Rows[1].Cells[3].Controls.Add(variableVal);

            variableNameLabelArray = new Label[MAX_NUMBER_VARIABLES];
            variableRequiredLabelArray = new Label[MAX_NUMBER_VARIABLES];
            variableTypeLabelArray = new Label[MAX_NUMBER_VARIABLES];
            variableValueTextBoxArray = new TextBox[MAX_NUMBER_VARIABLES];
            variableValueDropDownListArray = new DropDownList[MAX_NUMBER_VARIABLES];



            for (int j = 0; j < MAX_NUMBER_VARIABLES; j++)
            {
                variableNameLabelArray[j] = new Label();
                t.Rows[2 + j].Cells[0].Controls.Add(variableNameLabelArray[j]);

                variableRequiredLabelArray[j] = new Label();
                t.Rows[2 + j].Cells[1].Controls.Add(variableRequiredLabelArray[j]);

                variableTypeLabelArray[j] = new Label();
                t.Rows[2 + j].Cells[2].Controls.Add(variableTypeLabelArray[j]);

                variableValueTextBoxArray[j] = new TextBox();
                t.Rows[2 + j].Cells[3].Controls.Add(variableValueTextBoxArray[j]);
                variableValueDropDownListArray[j] = new DropDownList();
                t.Rows[2 + j].Cells[3].Controls.Add(variableValueDropDownListArray[j]);
            }
            for (int i = 0; i < variableNameLabelArray.Length; i++)
            {
                variableNameLabelArray[i].Visible = false;
                variableRequiredLabelArray[i].Visible = false;
                variableTypeLabelArray[i].Visible = false;
                variableValueTextBoxArray[i].Visible = false;
                variableValueDropDownListArray[i].Visible = false;

                //variableNameLabelArray[i] = null;
                //variableRequiredLabelArray[i] = null;
                //variableTypeLabelArray[i] = null;
                //variableValueTextBoxArray[i] = null;
            }
            //doNewVariableBinding();
            return t;
        }


        private Table createTable(int tableNum)
        {
            Table t;

            Style headerStyle = new Style();
            headerStyle.Font.Name = "Verdana";
            headerStyle.Font.Size = FontUnit.Parse("14pt");

            Style normalStyle = new Style();
            normalStyle.Font.Name = "Verdana";
            normalStyle.Font.Size = FontUnit.Parse("10pt");

            Style normalBoldStyle = new Style();
            normalBoldStyle.Font.Name = "Verdana";
            normalBoldStyle.Font.Size = FontUnit.Parse("12pt");
            normalBoldStyle.Font.Bold = true;

            switch (tableNum)
            {
                case 0:
                    t = createOverviewTab(normalStyle, normalBoldStyle);
                    break;
                case 1:
                    t = createStep1Tab(headerStyle, normalStyle, normalBoldStyle);
                    break;
                case 2:
                    t = createStep2Tab(headerStyle);
                    break;
                case 3:
                    t = createStep3Tab(headerStyle, normalStyle, normalBoldStyle);
                    break;
                case 4:
                    t = createStep4Tab(headerStyle, normalStyle, normalBoldStyle);
                    break;
                default:
                    // Error; bad times if it ever getes here, bad times
                    return null;
            }

            t.ID = "table" + tableNum;
            t.CellPadding = 10;

            return t;
        }

        #endregion

     
        #region table creation helper functions

        private Table createEmptyTable(int numRows, int numCols, int rowHeight, int rowWidth)
        {
            Table t = new Table();
            for (int i = 0; i < numRows; i++)
            {
                TableRow r = new TableRow();

                for (int j = 0; j < numCols; j++)
                {
                    TableCell c = new TableCell();
                    c.Height = rowHeight;
                    c.VerticalAlign = VerticalAlign.Top;
                    r.Cells.Add(c);
                }
                r.Width = Unit.Percentage(100);
                t.Rows.Add(r);
            }
            return t;
        }
        private Table createEmptyTableStatic(int numRows, int numCols, int rowHeight, int rowWidth)
        {
            Table t = new Table();
            for (int i = 0; i < numRows; i++)
            {
                TableRow r = new TableRow();

                for (int j = 0; j < numCols; j++)
                {
                    TableCell c = new TableCell();
                    c.Height = rowHeight;
                    c.VerticalAlign = VerticalAlign.Top;
                    r.Cells.Add(c);
                }
                r.Width = Unit.Pixel(rowWidth);
                t.Rows.Add(r);
            }
            return t;
        }

        #endregion
    }
}
